<?php
/**
 * Created by PhpStorm.
 * User: 86158
 * Date: 2021/6/15
 * Time: 23:04
 */

namespace App\Models\access;


use App\Models\Model;
use App\Models\User;
use App\Models\user\Depart;
use Illuminate\Support\Facades\DB;

class AccessVote extends Model
{
    protected $fillable = [
        'title',
        'intro',
        'status',
        'end_time',
        'score_level_best',
        'score_level_good',
        'score_level_general',
        'score_level_poor',
        'direct_leader_rate',
        'other_leader_rate',
        'main_leader_rate',
        'founder',
        'vote_user_id',
        'leader_id',
        'best_rate'
    ];

    public function setVoteUserIdAttribute($value){
        $this->attributes['vote_user_id'] = trim(implode($value, ','), ',');
    }

    public function setLeaderIdAttribute($value){
        $this->attributes['leader_id'] = trim(implode($value, ','), ',');
    }

    public function leader()
    {
        return $this->hasMany(AccessVoteLeader::class,'access_id');
    }
//
    public function member()
    {
        return $this->hasMany(AccessVoteMember::class,'access_id');
    }

    public function delete()
    {
        $access_id = $this->getKey();
        AccessVoteMember::where('access_id',$access_id)->update(['is_del'=>1]);
        AccessVoteLog::where('access_id',$access_id)->update(['is_del'=>1]);
        AccessVote::where('id',$access_id)->delete();
        return true;
    }

    /**
     * 检查投票活动自动结束
     */
    public static function checkStatus()
    {
        $data = self::where('status',1)->select(['id','status','end_time'])->get();
        foreach ($data as $item){
            if ($item['end_time'] < date("Y-m-d H:i:s")) {
                $item->status = 2;
                $item->save();
            }
        }
    }

    public function addAccessVote()
    {
        $data['title'] = "第二次考核";
        $data['intro'] = "测试数据";
        $data['end_time'] = "2021-06-23 00:00:00";
        $data['score_level_best'] = 90;
        $data['score_level_good'] = 80;
        $data['score_level_general'] = 70;
        $data['score_level_poor'] = 60;
        $data['direct_leader_rate'] = 0.40;
        $data['main_leader_rate'] = 0.40;
        $data['other_leader_rate'] = 0.20;
        $data['founder'] = "小松";
        $data['user_id'] = [1, 2];
        $data['leader'] = [2, 3];
        $data['title'] = "";
        if (bcadd(bcadd($data['direct_leader_rate'], $data['main_leader_rate'], 2), $data['other_leader_rate'], 2) != 1) {
            return false;
        }
        DB::beginTransaction();
        try {

            /*************活动主表数据************/
            $accessVoteData = [
                'title' => $data['title'],
                'intro' => $data['intro'],
                'end_time' => $data['end_time'],
                'founder' => $data['end_time'],
                'score_level_best' => $data['score_level_best'],
                'score_level_good' => $data['score_level_good'],
                'score_level_general' => $data['score_level_general'],
                'score_level_poor' => $data['score_level_poor'],
                'direct_leader_rate' => $data['direct_leader_rate'],
                'main_leader_rate' => $data['main_leader_rate'],
                'other_leader_rate' => $data['other_leader_rate']
            ];

            $accessVoteResult = self::firstOrCreate($accessVoteData);
            if (!$accessVoteResult) {
                return false;
            }


            /**********活动被考核人员********/
            foreach ($data['user_id'] as $item) {
                $accessVoteMemberData[] = [
                    'user_id' => $item,
                    'access_id' => $accessVoteResult['id']
                ];
            }
            $accessVoteMemberResult = AccessVoteMember::insert($accessVoteMemberData);

            /************活动领导人员***********/
            $superior_id = User::whereIn('id', $data['user_id'])->pluck('superior_id');
            $leader = User::whereIn('id', $data['leader'])->select(['id', 'level'])->get()->toArray();
            $leader = array_column($leader, null, 'id');

            foreach ($leader as $val) {
                if ($val['level'] == 1) {
                    return false;
                }
                if ($val['level'] == 2) {
                    if (in_array($superior_id, $val['id'])) {
                        $leader_type = 2;
                        $rate = $data['direct_leader_rate'];
                    } else {
                        $leader_type = 3;
                        $rate = $data['other_leader_rate'];
                    }
                }
                if ($val['level'] == 3) {
                    $leader_type = 1;
                    $rate = $data['main_leader_rate'];
                }
                $accessVoteLeaderData[] = [
                    'user_id' => $item,
                    'access_id' => $accessVoteResult['id'],
                    'leader_type' => $leader_type,
                    'rate' => $rate
                ];
            }
            $accessVoteLeaderResult = AccessVoteLeader::insert($accessVoteLeaderData);

            if (!$accessVoteLeaderResult || !$accessVoteMemberResult) {
                DB::rollBack();
                return false;
            }
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return false;
        }
    }

    /**
     * 考核投票列表
     * @param $user_id
     * @param string $keyword
     * @param int $pageNo
     * @param int $pageSize
     * @return array
     */
    public function lists($user_id, $keyword = '', $pageSize = 10,$pageNo = 1)
    {
        $user = User::where('id', $user_id)->first();
        if($keyword){
            $accessData = self::where('status', '>', 0)
                ->where('title','like','%'.$keyword.'%')
                ->orderBy('status','asc')
                ->orderByDesc('end_time')
                ->select(['id', 'title', 'end_time', 'status', 'founder'])->paginate();
        }else{
            $accessData = self::where('status', '>', 0)
                ->orderBy('status','asc')
                ->orderByDesc('end_time')
                ->select(['id', 'title', 'end_time', 'status', 'founder'])
                ->paginate();
        }

        $leaderAccessId = AccessVoteLeader::where('leader_id',$user_id)->pluck('access_id')->toArray();
        $userAccessId = AccessVoteMember::where('user_id',$user_id)->pluck('access_id')->toArray();
        foreach ($accessData as &$item) {
            $item['power'] = 1;
            if ($user['level'] == 2 || $user['level'] == 3) {
                if(!in_array($item['id'],$leaderAccessId)){
                    $item['power'] = 0;
                }
                $item['user_level'] = 2;
                $accessLeader = AccessVoteLeader::where('access_id', $item['id'])->where('leader_id', $user_id)->first();
                $item['vote_status'] = 0;
                if ($accessLeader) {
                    $item['vote_status'] = 1;
                }
            } else {
                if(!in_array($item['id'],$userAccessId)){
                    $item['power'] = 0;
                }
                $item['user_level'] = 1;
                $item['vote_status'] = 0;
            }
        }

        return $accessData;
    }

    /**
     * 用户投票
     * @param $user_id
     * @param $access_id
     */
    public function user_vote_detail($user_id, $access_id)
    {
        $user = User::where('id', $user_id)->first();
        if($user['level'] != 1){
            return false;
        }
        $accessData = AccessVoteMember::from('access_vote_members as m')
            ->where('m.access_id', $access_id)
            ->where('m.user_id', $user_id)
            ->leftJoin('access_votes as v', 'v.id', '=', 'm.access_id')
            ->select(['m.score','v.title','v.intro'])
            ->first();
        $accessData['name'] = $user['name'];
        return $accessData;
    }

    /**
     * 领导投票
     * @param $user_id
     * @param $access_id
     * @return bool|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function leader_vote_detail($user_id, $access_id)
    {
        $user = User::where('id', $user_id)->first();
        if ($user['level'] == 1) {
            return ['code' => 0,'msg' =>'成员无权限'];
        }
        if ($user['level'] == 1) {
            $accessData = AccessVoteMember::detail($user_id, $access_id);
        } else {
            $accessVoteData = AccessVote::where('id', $access_id)->first();
            if(!$accessVoteData){
                return ['code' => 0,'msg' =>'活动不存在'];
            }
//            $accessData['vote_best_count']
            $accessData['access_id'] = $accessVoteData['id'];
            $accessData['title'] = $accessVoteData['title'];
            $accessData['intro'] = $accessVoteData['intro'];
            $accessData['status'] = AccessVoteLeader::where('access_id',$access_id)->where('leader_id',$user_id)->value('status');
            $accessData['list'] = AccessVoteMember::from('access_vote_members as m')
                ->where('m.access_id', $access_id)
                ->leftJoin('users as u', 'm.user_id', '=', 'u.id')
                ->select(['u.name', 'm.user_id','m.remark','u.header_img', 'u.duty', 'u.depart_id'])
                ->get()->toArray();
            $accessData['vote_best_count'] = $user->best_count;
            $accessData['vote_best_dir_count'] = $user->best_dir_count;
//            if (AccessVoteLeader::where('access_id', $access_id)->where('leader_id', $user_id)->value('status') == 1) {
                foreach ($accessData['list'] as $k => $val) {
                    $logs = AccessVoteLog::where('user_id', $val['user_id'])
                        ->where('access_id', $access_id)
                        ->where('vote_user_id',$user_id)
//                        ->select(['remark', 'level'])
                        ->select(['level'])
                        ->first();
                    $accessData['list'][$k]['superior_id'] = Depart::getSuperiorId($val['depart_id']);
                    if ($logs) {
                        $accessData['list'][$k]['level'] = $logs['level'];
//                        $accessData['list'][$k]['remark'] = $val['remark'];
                    }else{
                        $accessData['list'][$k]['level'] = 0;
                    }
                }
//            }
        }

        foreach ($accessData['list'] as $key => $value) {
            if ($value['superior_id'] == $user_id) {
                $accessData['list'][$key]['is_direct'] = true;
                $value['is_direct'] = true;
                $temp = $value;
                unset($accessData['list'][$key]);
                array_unshift($accessData['list'], $temp);
            }else{
                $accessData['list'][$key]['is_direct'] = false;
            }
        }
        return $accessData;
    }

    public function voteCommit($user_id,$access_id,$vote)
    {
        $voteMembereStatus = AccessVoteLeader::where('access_id',$access_id)->where('leader_id',$user_id)->where('status',1)->first();
        if($voteMembereStatus){
            return ['code'=>0,'msg'=>'请勿重复投票'];
        }

        /****投票人信息****/
        $voteUser = User::where('id',$user_id)->first();

        /****考核信息*****/
        $access = AccessVote::where('id',$access_id)->where('status','=',1)->first();

        if(!$access){
            return ['code'=>0,'msg'=>'考核不存在或已结束'];
        }

        /*********投票员工数量判定*********/
        $voteCount = AccessVoteMember::where('access_id',$access_id)->count();
        if($voteCount != count($vote)){
            return ['code'=>0,'msg'=>'请对所有人投票'];
        }

        /********评分等级对应分数********/
        $scoreArr = [
            1 => $access['score_level_best'],
            2 => $access['score_level_good'],
            3 => $access['score_level_general'],
            4 => $access['score_level_poor']
        ];



        DB::beginTransaction();
        try {
            /******需要投票领导数量*****/
            $accessVoteLeaderCount = AccessVoteLeader::where('access_id',$access_id)->count();

            /*******循环处理每个被投票人的情况******/
            $bestCount = 0;
            $bestDirCount = 0;
            foreach ($vote as $item){
                if(!isset($item['voted_user_id'])) return ['code'=>0,'msg'=>'voted_user_id参数缺失'];
                if(!isset($item['level'])) return ['code'=>0,'msg'=>'level参数缺失'];
//                if(!isset($item['remark'])) return false;

                /********获取该领导对应投票得分占比*******/
                $rate = 0;
                $user = User::where('id',$item['voted_user_id'])->first();
                $user['superior_id'] = Depart::getSuperiorId($user['depart_id']);
                if($voteUser['level'] == 3){
                    $rate = $access['main_leader_rate'];
                    $leader_type = 1;
                }
                if($voteUser['level'] == 2 && $user_id == $user['superior_id']){
                    $rate = $access['direct_leader_rate'];
                    $leader_type = 2;
                    if($item['level'] == 1) $bestDirCount += 1;
                }
                if($voteUser['level'] == 2 && $user_id != $user['superior_id']){
                    $rate = $access['other_leader_rate'];
                    $leader_type = 3;
                }
                if($item['level'] == 1){
                    $bestCount += 1;
//                    $bestRate = bcdiv($bestCount,count($vote),2);
                    if($bestCount > $voteUser['best_count']){
                        return ['code'=>0,'msg'=>'好评数高于了'.$voteUser['best_count']];
                    }
                    if($bestDirCount > $voteUser['best_dir_count']){
                        return ['code'=>0,'msg'=>'直属下属好评数高于了'.$voteUser['best_dir_count']];
                    }
                }
                /*******被投票人得分******/
                $levelScore = $scoreArr[$item['level']];
                $score = bcmul($rate,$levelScore,2);

                /*********每个被投票人对应记录*******/
                $logs = [
                    'vote_user_id' => $user_id,
                    'user_id' => $item['voted_user_id'],
                    'access_id' => $access_id,
                    'level' => $item['level'],
                    'score' => $score,
//                    'remark' => isset($item['remark']) ? $item['remark'] : '',
                    'leader_type' => $leader_type,
                    'level_score' => $levelScore
                ];
                $accessVoteResult = AccessVoteLog::create($logs);

                /********若被投票人已被所有投票人投票后计算总得分*******/
                $accessVoteLogCount = AccessVoteLog::where('user_id',$item['voted_user_id'])->where('access_id',$access_id)->count();
                if($accessVoteLogCount == $accessVoteLeaderCount){
                    $mainLeaderscore = AccessVoteLog::where('user_id',$item['voted_user_id'])
                        ->where('access_id',$access_id)->where('leader_type',1)->avg('score');
                    $directLeaderScore = AccessVoteLog::where('user_id',$item['voted_user_id'])
                        ->where('access_id',$access_id)->where('leader_type',2)->avg('score');
                    $otherLeaderScore = AccessVoteLog::where('user_id',$item['voted_user_id'])
                        ->where('access_id',$access_id)->where('leader_type',3)->avg('score');
                    $totalScore = bcadd(bcadd($mainLeaderscore,$directLeaderScore,2),$otherLeaderScore,2);
                    AccessVoteMember::where('user_id',$item['voted_user_id'])
                        ->where('access_id',$access_id)->update(['score'=>$totalScore,'status'=>1]);
                }

                if(!$accessVoteResult){
                    DB::rollBack();
                    return ['code'=>0,'msg'=>'投票记录失败'];
                }
            }

            /********更新每个领导投票状态********/
            $updateAccessVoteLeader = AccessVoteLeader::where('leader_id',$user_id)
                ->where('access_id',$access_id)
                ->update(['status'=>1]);
            if(!$updateAccessVoteLeader){
                return ['code'=>0,'msg'=>'投票更新失败'];
            }
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            return ['code'=>0,'msg'=>'投票失败'];
        }
        return true;
    }
}